//
//  RenameViewController.swift
//
//  Created by Evan Xie on 2018/5/19.
//

import Cocoa

class RenameViewController: NSViewController {
    
    enum State: Int {
        case initial
        case folderSelected
        case working
        case done
    }
    
    enum WorkingMode {
        case rename
        case delete
    }
    
    fileprivate var fileURLGenerator: FileURLGenerator!
    
    fileprivate var allFileURLs = [URL]()
    fileprivate var selectedDirectoryURL: URL?
    fileprivate var fileManager = FileManager.default
    fileprivate var pannel: NSOpenPanel!

    fileprivate var workingMode: WorkingMode!
    
    @IBOutlet weak var selectedFolderLabel: NSTextField!
    @IBOutlet weak var newFileNameTextField: NSTextField!
    @IBOutlet weak var sequenceTextField: NSTextField!
    @IBOutlet weak var sequenceOffsetTextField: NSTextField!
    @IBOutlet weak var renameButton: NSButton!
    @IBOutlet weak var deleteButton: NSButton!
    @IBOutlet weak var openFolderButton: NSButton!
    
    fileprivate var currentState = State.initial {
        didSet {
    
            DispatchQueue.main.async {
                switch self.currentState {
                case .initial:
                    self.renameButton.title = "Start Renaming"
                    self.deleteButton.title = "Start Deleting"
                    self.newFileNameTextField.isEnabled = false
                    self.newFileNameTextField.stringValue = ""
                    self.openFolderButton.isEnabled = true
                case .folderSelected:
                    self.renameButton.title = "Start Renaming"
                    self.deleteButton.title = "Start Deleting"
                    self.newFileNameTextField.isEnabled = true
                    self.openFolderButton.isEnabled = true
                    self.newFileNameTextField.stringValue = ""
                    
                case .working:
                    self.updateUIWhenWoring()
                    self.newFileNameTextField.isEnabled = false
                    self.openFolderButton.isEnabled = false
                case .done:
                    self.updateUIWhenDone()
                    self.newFileNameTextField.isEnabled = false
                    self.openFolderButton.isEnabled = true
                }
            }
        }
    }
    
    fileprivate func updateUIWhenWoring() {
        switch workingMode! {
        case .rename:
            self.renameButton.title = "Renaming, please wait..."
        case .delete:
            self.deleteButton.title = "Deleting, please wait..."
        }
    }
    
    fileprivate func updateUIWhenDone() {
        switch workingMode! {
        case .rename:
            self.renameButton.title = "Done"
        case .delete:
            self.deleteButton.title = "Done"
        }
    }
    
    override func viewDidLoad() {
        super.viewDidLoad()
        let config = FileURLGenerator.Config(referredFileURL: URL(fileURLWithPath: "default"))
        fileURLGenerator = FileURLGenerator(config: config)
    }


    override var representedObject: Any? {
        didSet {
        // Update the view, if already loaded.
        }
    }

    @IBAction func openFolder(_ sender: Any) {
        
        guard currentState != .working else { return }
        
        currentState = .initial
        
        pannel = NSOpenPanel()
        pannel.canChooseFiles = false
        pannel.canChooseDirectories = true
        pannel.allowsMultipleSelection = false
        
        pannel.begin { (response) in
            guard response == NSApplication.ModalResponse.OK else { return }
            self.selectedDirectoryURL = self.pannel.url
            guard let selectedDirURL = self.pannel.url else { return }
            self.allFileURLs.removeAll()
            self.currentState = .folderSelected
            self.allFileURLs.append(contentsOf: FileManager.fileURLs(at: selectedDirURL))
            self.selectedFolderLabel.stringValue = selectedDirURL.path
        }
    }
    
    @IBAction func startDeleting(_ sender: Any) {
        
        guard self.selectedDirectoryURL != nil && currentState == .folderSelected else { return }
        
        let filenameFilter = newFileNameTextField.stringValue
        if filenameFilter.isEmpty { return }
        
        workingMode = .delete
        currentState = .working
        
        DispatchQueue.global().async {
            for fileURL in self.allFileURLs {
                if fileURL.path.contains(filenameFilter) {
                    do {
                        try FileManager.default.removeItem(at: fileURL)
                    } catch {
                        print(error)
                    }
                }
            }
        }
    }
    
    @IBAction func startRenaming(_ sender: Any) {
        
        guard self.selectedDirectoryURL != nil && currentState == .folderSelected else {
            showAlert("Please select a folder.")
            return
        }
        
        let renamingFilename = newFileNameTextField.stringValue
        if renamingFilename.lengthOfBytes(using: .utf8) == 0 {
            showAlert("New file name can not be empty!")
            return
        }
        
        let digitsOfSequence = sequenceTextField.integerValue
        if digitsOfSequence <= 0 || digitsOfSequence > 8 {
            showAlert("Digits of sequence must be in [1, 8]")
            return
        }
        
        var offsetSequence = abs(sequenceOffsetTextField.integerValue)
        if offsetSequence < 1 {
            offsetSequence = 1
        }
        
        workingMode = .rename
        currentState = .working
        let referredURL = selectedDirectoryURL!.appendingPathComponent(renamingFilename)
        let config = FileURLGenerator.Config(referredFileURL: referredURL,
                                             sequentialNumberFormat: .fixedWidth(digitsOfSequence),
                                             boundSymbol: "-",
                                             startSequenceNumber: offsetSequence)
        fileURLGenerator.resetConfig(config)
        
        DispatchQueue.global().async {
            for url in self.allFileURLs {
                let newURL = self.fileURLGenerator.nextFileURL(withPathExtension: url.pathExtension)
                do {
                    try FileManager.default.moveItem(at: url, to: newURL)
                } catch {
                    print(error)
                }
            }
            self.allFileURLs.removeAll()
            self.selectedDirectoryURL = nil
            self.currentState = .done
        }
    }
    
    fileprivate func showAlert(_ message: String) {
        let alert = NSAlert()
        alert.messageText = message
        alert.addButton(withTitle: "Got it")
        alert.runModal()
    }
}

